package jp.co.cos.ittrick.channel.service;

import jp.co.cos.ittrick.channel.common.exception.DatastorePutException;
import jp.co.cos.ittrick.channel.common.exception.DoubleInsertException;
import jp.co.cos.ittrick.channel.meta.CategoryModelMeta;
import jp.co.cos.ittrick.channel.model.CategoryModel;

import org.slim3.datastore.Datastore;
import org.slim3.memcache.Memcache;

import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.Transaction;


public class CategoryService {

    /**
     * キーによるカテゴリの取得
     * @param pkKey
     * @return ChannelModel
     */
    public CategoryModel getCategoryByKey(int categoryKey) {
        Key categoryPkKey = Datastore.createKey(CategoryModelMeta.get(), categoryKey);

        // Memcache に存在した場合はMemcache内のmodelを返す
        CategoryModel categoryModel = Memcache.get(categoryPkKey);
        if(categoryModel != null) return categoryModel;

        categoryModel = Datastore.getOrNull(CategoryModel.class, categoryPkKey);
        if(categoryModel != null) Memcache.put(categoryPkKey, categoryModel);

        return categoryModel;
    }

    /**
     * Insert
     * @param pkKey
     * @param model
     * @return key
     * @throws DoubleInsertException
     * @throws DatastorePutException
     */
    public Key insert(CategoryModel model)
    throws DoubleInsertException, DatastorePutException {

        // キーの作成
        Key key = null;

        // insert
        Transaction tx = Datastore.beginTransaction();
        try {
            key = Datastore.put(tx, model);
            tx.commit();
        }
        catch (Exception e) {
            if (tx.isActive()) {
                tx.rollback();
            }
            throw new DatastorePutException();
        }

        return key;
    }


    /**
     * Update
     * @param model
     * @throws DatastorePutException
     */
    public void update(CategoryModel model) throws DatastorePutException {

        // Local Transaction の開始
        Transaction tx = Datastore.beginTransaction();

        try {
            // バージョンによる変更チェック
            Datastore.get(tx, CategoryModelMeta.get(), model.getKey(), model.getVersion());
            // 更新
            Datastore.put(tx, model);

            tx.commit();

        }catch (Exception e) {
            if (tx.isActive()) {
                tx.rollback();
            }
            throw new DatastorePutException();
        }
    }


    /**
     * 削除
     * @param serialPkKey
     * @param articleNum
     * @param articlePageNum
     * @throws Exception
     */
    public void delete(int pkKey) throws Exception {

        CategoryModel categoryModel = getCategoryByKey(pkKey);
        Key key = categoryModel.getKey();

        // Local Transaction の開始
        Transaction tx = Datastore.beginTransaction();

        try {
            Datastore.delete(tx, key);

            tx.commit();

        }catch (Exception e) {
            if (tx.isActive()) {
                tx.rollback();
            }
            throw e;
        }
    }

}
